---
title: ShaderLab
---

`ShaderLab` 是一个针对 Galacean 引擎打造的 `Shader` 包装语言，它允许开发人员使用熟悉的 `GLSL` 语法编写自定义 `Shader`，同时提供了额外的高级抽象和管理特性以增强开发效率。通过 `ShaderLab`，开发者能够更便捷地定义材质属性、渲染配置和其他效果。尽管 `ShaderLab` 为着色器的编写引入了便利性，但它并不取代 `GLSL`，而是与之兼容。开发者可以在 `ShaderLab` 框架内编写原生 `GLSL` 代码块，享受两者的结合优势。

## 语法介绍

`ShaderLab` 语法骨架如下:

```glsl
Shader "ShaderName" {
  ...
  Editor {
    ...
  }
  ...
  SubShader "SubShaderName" {
    ...
    Pass "PassName" {
      ...
    }
    ...
  }
  ...
}
```

### ShaderLab 主要语法模块

| 语法模块 | 描述 |
| :- | :-- |
| [Shader](./shader) | ShaderLab 中通过 `Shader` 模块声明一个 Shader 对象，开发者可以在该模块中添加材质属性、绑定 [Shader UI 脚本](./script)、[声明全局变量](./global)等 |
| [Editor](./ediotr) | 开发者通过 `Editor` 模块对材质 Inspector 面板进行定制 |
| [SubShader](./subShader) | 在 `SubShader` 中指定 [Tag](/apis/galacean/#SubShader-setTag)，添加 ShaderPass，使用 `UsePass` 指令 |
| [Pass](./pass) | 开发者通过 `Pass` 模块声明 [ShaderPass](/apis/galacean/#ShaderPass) 对象 |

## Unlit ShaderLab 示例

```ts showLineNumbers {2,18,21}
Shader "ShaderName" {
    Editor {
      Properties {
        material_BaseColor("Main Color", Color) = (0, 0, 0, 1);
        material_BaseTexture("Texture", Texture2D);
        material_AlphaCutoff("Alpha Cutoff", Range(0, 1, 0.01)) = 0;

        Header("Common"){
          isTransparent("Transparent", Boolean) = false;
          renderFace("Render Face", Enum(Front:0, Back:1, Double:2)) = 0;
          blendMode("Blend Mode", Enum(Normal:0, Additive:1)) = 0;
        }
      }

      UIScript "${uiScriptPath}";
    }

    SubShader "Default" {
      UsePass "pbr/Default/ShadowCaster"

      Pass "Pass0" {
        DepthState {
          WriteEnabled = depthWriteEnabled;
        }

        BlendState {
          Enabled = blendEnabled;
          SourceColorBlendFactor = sourceColorBlendFactor;
          DestinationColorBlendFactor = destinationColorBlendFactor;
          SourceAlphaBlendFactor = sourceAlphaBlendFactor;
          DestinationAlphaBlendFactor = destinationAlphaBlendFactor;
        }

        RasterState{
          CullMode = rasterStateCullMode;
        }

        RenderQueueType = renderQueueType;

        struct Attributes {
          vec3 POSITION;
          vec2 TEXCOORD_0;
          vec4 JOINTS_0;
          vec4 WEIGHTS_0;
        };

        struct Varyings {
          vec2 uv;
        };

        #include "Common.glsl"
        #include "Skin.glsl"
        #include "Transform.glsl"

        vec4 material_BaseColor;
        float material_AlphaCutoff;
        sampler2D material_BaseTexture;

        VertexShader = vert;
        FragmentShader = frag;

        Varyings vert(Attributes attr) {
          Varyings v;

          vec4 position = vec4(attr.POSITION, 1.0);

          // Skin
          #ifdef RENDERER_HAS_SKIN
            mat4 skinMatrix = getSkinMatrix(attr);
            position = skinMatrix * position;
          #endif

          gl_Position = renderer_MVPMat * position;
          v.uv = attr.TEXCOORD_0;

          return v;
        }

        void frag(Varyings v) {
          vec4 baseColor = material_BaseColor;

          #ifdef MATERIAL_HAS_BASETEXTURE
              vec4 textureColor = texture2D(material_BaseTexture, v.uv);
              #ifndef ENGINE_IS_COLORSPACE_GAMMA
                  textureColor = gammaToLinear(textureColor);
              #endif
              baseColor *= textureColor;
          #endif

          #ifdef MATERIAL_IS_ALPHA_CUTOFF
              if( baseColor.a < material_AlphaCutoff ) {
                  discard;
              }
          #endif

          gl_FragColor = baseColor;

          #ifndef ENGINE_IS_COLORSPACE_GAMMA
              gl_FragColor = linearToGamma(gl_FragColor);
          #endif

        }
    }
  }
}
```
